<!DOCTYPE html>
<html>

<head>
  <title>shown_test.html</title>
  <script src="test_bootstrap.js"></script>
  <script type="text/javascript">
    goog.require('bot');
    goog.require('bot.dom');
    goog.require('bot.locators');
    goog.require('bot.userAgent');
    goog.require('goog.dom');
    goog.require('goog.style');
    goog.require('goog.testing.ExpectedFailures');
    goog.require('goog.testing.jsunit');
    goog.require('goog.userAgent');
    goog.require('goog.userAgent.platform');
  </script>

  <style>
    #box {
      border: 1px solid black;
    }

    #box ul {
      height: 250px;
      overflow: hidden;
    }

    #box ul>li {
      height: 50px;
    }

    #box ul>li>a {
      height: 26px;
    }
  </style>
  <script type="text/javascript">
    var isShown = bot.dom.isShown;
    var findElement = bot.locators.findElement;
    var expectedFailures;

    function setUp() {
      expectedFailures = new goog.testing.ExpectedFailures();
    }

    function tearDown() {
      expectedFailures.handleTearDown();
      goog.style.setStyle(document.body, 'display', 'block');
      goog.style.setStyle(document.body, 'overflow', 'auto');
    }

    function testMustBeGivenAnElement() {
      assertThrows(function () {
        isShown(undefined);
      });
    }

    function testBodyShown() {
      assertTrue(isShown(document.body));
    }

    function testBodyAlwaysShown() {
      goog.style.setStyle(document.body, 'display', 'none');
      assertTrue("BODY element must *always* be shown", isShown(document.body));
    }

    function testCanDetermineIfAnElementIsShownOrNot() {
      assertTrue(isShown(findElement({ id: 'displayed' })));
      assertFalse(isShown(findElement({ id: 'none' })));
      assertFalse(isShown(findElement({ id: 'suppressedParagraph' })));
      assertFalse(isShown(findElement({ id: 'hidden' })));
    }

    function testIsShownTakesIntoAccountParentDisplay() {
      var parent = findElement({ id: 'hiddenparent' });
      assertFalse('parent is explicitly set to display:none',
        isShown(parent));

      var childDiv = findElement({ id: 'hiddenchild' });
      var hiddenLink = findElement({ id: 'hiddenlink' });

      assertFalse(isShown(childDiv));
      assertFalse(isShown(hiddenLink));
    }


    function testIsShownTakesIntoAccountParentVisibility() {
      var parent = findElement({ id: 'hiddenFormFields' });
      var child = findElement({ id: 'untogglable' });

      expectedFailures.expectFailureFor(
        goog.userAgent.IE && goog.userAgent.platform.isVersion(6) &&
        !goog.userAgent.platform.isVersion(6.1),
        'Vista fails this test, have not figured it out yet...');
      // TODO: Figure it out
      expectedFailures.run(function () {
        assertFalse(isShown(parent));
        assertFalse(isShown(child));
      });
    }

    function testCountElementsAsVisibleIfStylePropertyHasBeenSet() {
      var shown = findElement({ id: 'visibleSubElement' });
      assertTrue(isShown(shown));
    }

    function testHiddenInputElementsAreNeverVisible() {
      var hidden = findElement({ name: 'hidden' });
      assertFalse(isShown(hidden));
    }


    function testElementWithZeroHeightIsNotConsideredDisplayed() {
      // IE6 doesn't render the element correctly for the test to work.
      if (goog.userAgent.IE && bot.userAgent.isEngineVersion(6)) {
        return;
      }
      var zeroHeight = findElement({ id: 'zeroheight' });
      assertFalse(isShown(zeroHeight));
    }


    function testElementWithZeroWidthIsNotConsideredDisplayed() {
      // IE6 doesn't render the element correctly for the test to work.
      if (goog.userAgent.IE && bot.userAgent.isEngineVersion(6)) {
        return;
      }

      var zeroWidth = findElement({ id: 'zerowidth' });
      assertFalse(isShown(zeroWidth));
    }

    function testElementWithOnlyWhitespaceReturnsConsistentResults() {
      var span = findElement({ id: 'onlyWhitespace' });
      // Make sure we report the same result every time. Both will be true in
      // most browsers, except IE7 and earlier, where they will both be false.
      assertEquals(isShown(span), isShown(span));
    }

    function testCorrectlyDeterminesVisibilityViaDisplayStyle() {
      var span = findElement({ id: 'visibleSpan' });
      assertFalse(isShown(span));
    }


    function testThrowsErrorIfPassedATextNode() {
      var textNode = findElement({ id: 'displayed' }).firstChild;
      var err = assertThrows('Argument to isShown must be of type Element',
        function () {
          isShown(textNode);
        });
      assertEquals('Argument to isShown must be of type Element', err.message);
    }


    function testOptionShownWhenEnclosingSelectShown() {
      var option = findElement({ id: 'shownOption' });
      assertTrue(isShown(option));
    }


    function testOptionNotShownWhenEnclosingSelectNotShown() {
      var option = findElement({ id: 'hiddenOption' });
      assertFalse(isShown(option));
    }


    function testOrphanOptionIsNotShown() {
      var option = findElement({ id: 'orphanOption' });
      // In some browsers, an orphan option is not rendered at all.
      assertFalse(!!option && isShown(option));
    }

    function testMapShownWhenImageShown() {
      var map = findElement({ id: 'shownMap' });
      assertTrue(isShown(map));
    }

    function testMapNotShownWhenImageNotShown() {
      var map = findElement({ id: 'hiddenImageMap' });
      assertFalse(isShown(map));
    }

    function testMapNotShownWhenNoImage() {
      var map = findElement({ id: 'noImageMap' });
      assertFalse(isShown(map));
    }

    function testMapNotShownWhenNoName() {
      var map = findElement({ id: 'noNameMap' });
      assertFalse(isShown(map));
    }

    function testAreaShownWhenEnclosingMapShown() {
      var area = findElement({ id: 'shownArea' });
      assertTrue(isShown(area));
    }

    function testAreaNotShownWhenEnclosingMapNotShown() {
      var area = findElement({ id: 'hiddenArea' });
      assertFalse(isShown(area));
    }

    function testOrphanAreaIsNotShown() {
      var area = findElement({ id: 'orphanArea' });
      // In some browsers, an orphan area is not rendered at all.
      assertFalse(!!area && isShown(area));
    }

    function testElementWithNestedBlockLevelElementShown() {
      var containsNestedBlock = findElement({ id: 'containsNestedBlock' });
      assertTrue(isShown(containsNestedBlock));
    }

    function testZeroOpacityMakesElementNotShown() {
      var transparent = findElement({ id: 'transparent' });
      assertFalse(isShown(transparent));
    }

    function testTitleIsNotShown() {
      var title = findElement({ tagName: 'title' });
      assertFalse(isShown(title));
    }

    function testTitleOfFrameWindowNotShown() {
      var iframe = findElement({ id: 'iframe' });
      var iframeDoc = goog.dom.getFrameContentDocument(iframe);
      var iframeTitle = findElement({ tagName: 'title' }, iframeDoc);
      assertFalse(isShown(iframeTitle));
    }

    function testTwoEmptyDivsAreZeroSizedAndNotShown() {
      var element = goog.dom.createDom('div', null,
        goog.dom.createDom('div'));
      document.body.appendChild(element);
      var size = bot.dom.getClientRect(element);
      // Width will be equivalent of width:100%
      assertEquals('Should have 0 height', 0, size.height);
      assertFalse(isShown(element));
    }

    function testZeroSizedDivIsShownIfDescendantHasSize() {
      if (goog.userAgent.IE && !bot.userAgent.isProductVersion(7)) {
        return;
      }
      var element = goog.dom.createDom('div',
        { id: 'ZeroSizedDiv', style: 'width:0;height:0' },
        goog.dom.createDom('div', null,
          goog.dom.createDom('img', {
            src: 'testdata/map.png',
            height: '126',
            width: '364'
          })));
      document.body.appendChild(element);
      var size = bot.dom.getClientRect(element);
      assertEquals('Should have 0 width', 0, size.width);
      assertEquals('Should have 0 height', 0, size.height);
      assertTrue(isShown(element));
    }

    function testZeroSizedAbsolutePositionedBlockElementsAreShownIfDescendantHasSize() {
      var div = goog.partial(goog.dom.createDom, 'div');

      function position(element, left, top, opt_zIndex) {
        element.style.position = 'absolute';
        element.style.left = left;
        element.style.top = top;
        if (opt_zIndex)
          element.style.zIndex = opt_zIndex;
        return element;
      }

      function size(element, width, height) {
        element.style.width = width;
        element.style.height = height;
        return element;
      }

      var root = position(div(), 0, 0, 1),
        child = position(div(), 0, 0, 100),
        grandChild = position(div(), 0, 0),
        greatGrandChild = size(position(div(), 0, 0), '250px', '250px');

      grandChild.appendChild(greatGrandChild);
      child.appendChild(grandChild);
      root.appendChild(child);
      document.body.appendChild(root);

      var size = bot.dom.getClientRect(root);
      assertEquals('Should have 0 width', 0, size.width);
      assertEquals('Should have 0 height', 0, size.height);
      assertTrue('Should still be considered shown', isShown(root));
    }

    /** @see http://code.google.com/p/selenium/issues/detail?id=2922 */
    function testOptionsInInvisibleSelectAreStillShown() {
      var select = goog.dom.$('invisiSelect');
      assertEquals(0, bot.dom.getOpacity(select));
      assertFalse(bot.dom.isShown(select));
      assertTrue('Select should be visible when ignoring opacity',
        bot.dom.isShown(select, true));
      assertTrue(bot.dom.isShown(select.firstChild));
    }

    /** @see http://code.google.com/p/selenium/issues/detail?id=1941 */
    function testMapsForInvisibleImagesAreShownWhenIgnoringOpacity() {
      var img = goog.dom.$('invisiImg');
      assertEquals(0, bot.dom.getOpacity(img));
      assertFalse(bot.dom.isShown(img));
      assertTrue(bot.dom.isShown(img, true));

      var map = goog.dom.$('invisiShownMap');
      assertFalse(bot.dom.isShown(map));
      assertTrue(bot.dom.isShown(map, true));

      var area = goog.dom.$('invisiShownArea');
      assertFalse(bot.dom.isShown(area));
      assertTrue(bot.dom.isShown(area, true));
    }

    function testNoscriptElementIsNotShown() {
      var noscript = findElement({ id: 'noscript' });
      assertFalse(isShown(noscript));
    }

    function testThatItemsHiddenWithOverflowHiddenAreFalse() {
      if (goog.userAgent.IE && !bot.userAgent.isProductVersion(7)) {
        return;
      }
      var target = findElement({ id: 'target' });
      assertFalse(isShown(target));
    }

    function testThatItemsAreConsideredInvisbleIfAbsolutePositionIsNotInCascade() {
      var target = findElement({ id: 'iHaveAbsolutePosition' });
      assertFalse(isShown(target));
    }

    function testZeroSizeElemWithOverflowHiddenAndTextNotShown() {
      var target = findElement({ id: 'bug5022' });
      assertFalse(isShown(target));
    }

    function testOverflowHiddenWithFixedPositionChild() {
      var target = findElement({ id: 'overflowHiddenWithFixedPositionChild' });
      var child = findElement({ id: 'fixedPositionChild' });
      goog.dom.removeChildren(child);
      assertFalse(isShown(target));
      goog.dom.setTextContent(child, 'some content');
      assertTrue(isShown(target));
    }

    function testThatElementIsShownWithZIndex() {
      assertTrue(isShown(findElement({ id: 'bug5109' })));
    }

    function testNegativePositionedParentWithPositionPositionedChildIsShown() {
      var target = findElement({ id: 'negativePositionWithPositivePositionChildren' });
      assertTrue(isShown(target));
    }

    function testCanNotSeeElementWithHiddenAttribute() {
      expectedFailures.expectFailureFor(
        (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(11)) ||
        bot.userAgent.ANDROID_PRE_GINGERBREAD,
        'IE and Android Froyo do not understand hidden attribute');
      var elem = findElement({ id: 'html5hidden' });
      expectedFailures.run(function () {
        assertFalse(isShown(elem));
      });
    }

    function testTableRowDefaultVisibility() {
      var elem = findElement({ id: 'visible-row' });
      assertTrue(isShown(elem));
      assertTrue(isShown(elem.firstChild));
    }

    function testTableRowCollapsedVisibility() {
      expectedFailures.expectFailureFor(
        (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(8)),
        'IE does not support visibility:collapsed until IE8');
      var elem = findElement({ id: 'collapsed-row' });
      expectedFailures.run(function () {
        assertFalse(isShown(elem));
        assertFalse(isShown(elem.firstChild));
      });
    }

    function testVisibleTableRowAfterCollapsedRow() {
      var elem = findElement({ id: 'post-collapsed-row' });
      assertTrue(isShown(elem));
      assertTrue(isShown(elem.firstChild));
    }

    function testDisplayContentsOverflowIgnored() {
      assertTrue(isShown(findElement({ id: 'displayContentsInput' })));
    }

    function testDetailsSummaryVisibility() {
      var summary = findElement({ id: 'summary' });
      assertTrue(isShown(summary));
    }

    function testDetailsNonSummaryDescendantsVisibility() {
      var contents = findElement({ id: 'non-summary' });
      assertFalse(isShown(contents));
      assertFalse(isShown(contents.firstChild));
    }

    function testContentVisibleHidden() {
      var content = findElement({ id: 'contentVisibility' });
      assertFalse(isShown(content));
      assertFalse(isShown(findElement({ id: 'b' }, content)));
    }

    function testNestedTextNode() {
      var content = findElement({ id: 'nestedTextNode' });
      assertFalse(isShown(content));
    }
  </script>

  <style type="text/css">
    #nav {
      padding: 0;
      margin: 0;
      list-style: none;
    }

    #nav li {
      float: left;
      position: relative;
      width: 10em;
    }

    #nav li ul {
      display: none;
      position: absolute;
      top: 1em;
      left: 0;
    }

    #nav li>ul {
      top: auto;
      left: auto;
    }

    #nav li:hover ul,
    #nav li.over ul {
      display: block;
      background: white;
    }

    #transparent {
      opacity: 0;
      /* non IE */
      filter: alpha(opacity=0);
      /* IE 6+ */
    }

    #zeroheight,
    #zerowidth {
      border: 0;
      padding: 0;
      margin: 0;
    }

    #zerowidth {
      width: 0;
      height: 70px;
    }

    #zeroheight {
      width: 70px;
      height: 0;
    }

    box-popup {
      border: 1px;
      min-width: 150px;
    }

    #box {
      border: 1px solid black;
    }

    #box ul {
      height: 250px;
      overflow: hidden;
    }

    #box ul>li {
      height: 50px;
    }

    #box ul>li>a {
      height: 26px;
    }
  </style>
</head>

<body>
  <div style="left: 30px; top: 10px; visibility: visible; position: absolute; overflow: visible;" class="box-popup"
    id="suggest">
    <p>Hello world. I like cheese.</p>
  </div>
  <div>
    <p id="displayed">Displayed</p>

    <p id="transparent">Transparent</p>

    <form action="#"><input type="hidden" name="hidden" /></form>

    <p id="none" style="display: none;">Display set to none</p>

    <p id="hidden" style="visibility: hidden;">Hidden</p>

    <div id="hiddenparent" style="height: 2em; display: none;">
      <div id="hiddenchild">
        <a href="#" id="hiddenlink">ok</a>
      </div>
    </div>

    <div id="hiddenFormFields" style="visibility: hidden;">
      <span>
        <input id="unclickable" />
        <input type="checkbox" id="untogglable" checked="checked" />Check box you can't see
      </span>
    </div>

    <div style="display:none">
      <span id="visibleSpan" style="display:block">cheese puffs</span>
    </div>

    <p id="outer" style="visibility: hidden">A
      <b id="visibleSubElement" style="visibility: visible">sub-element that is
        explicitly visible</b> using CSS visibility=visible
    </p>

    <noscript id='noscript'>Noscript subelement that is not visible</noscript>
  </div>

  <img id="zeroheight" src="testdata/map.png">
  <img id="zerowidth" src="testdata/map.png">

  <p id="suppressedParagraph" style="display: none">A paragraph suppressed using CSS display=none</p>

  <select>
    <option id="shownOption" style="display:none;visibility:hidden;">
  </select>
  <select style="display:none;">
    <option id="hiddenOption">
  </select>
  <option id="orphanOption"></option>

  <label>invisible select:
    <select id="invisiSelect" style="opacity:0; filter:alpha(opacity=0)">
      <option>Test</option>
    </select>
  </label>

  <img usemap="#shownMap" src="testdata/map.png">
  <map id="shownMap" name="shownMap">
    <area id="shownArea" shape="rect" coords="0,0,1,1" href="#">
  </map>
  <img usemap="#hiddenImageMap" src="testdata/map.png" style="visibility: hidden">
  <map id="hiddenImageMap" name="hiddenImageMap">
    <area id="hiddenArea" shape="rect" coords="0,0,1,1" href="#">
  </map>
  <map id="noImageMap" name="noImageMap"></map>
  <map id="noNameMap"></map>
  <img id="invisiImg" usemap="#invisiShownMap" src="testdata/map.png" width="91" height="31"
    style="opacity:0; filter:alpha(opacity=0)">
  <map id="invisiShownMap" name="invisiShownMap">
    <area id="invisiShownArea" shape="rect" coords="0,0,1,1" href="#">
  </map>

  <area id="orphanArea" shape="rect" coords="0,0,1,1" href="#"></area>

  <a id="containsNestedBlock" href="#">
    <div style="display:block;">text</div>
  </a>

  <iframe id="iframe" src="testdata/iframe_page.html"></iframe>

  <span id="onlyWhitespace"> </span>
  <div id="box">
    <ul id="list1">
      <li><a>Item 1</a></li>
      <li><a>Item 2</a></li>
      <li><a>Item 3</a></li>
      <li><a>Item 4</a></li>
      <li><a>Item 5</a></li>
      <li><a>Item 6</a></li>
      <li><a>Item 7</a></li>
      <li id="target"><a>Item 8</a></li>
    </ul>
  </div>
  <div id="grandparent" style="display:none;width:10px;">
    <div id="parent" style="position:absolute;right:10px;">
      <div id="iHaveAbsolutePosition" style="display:block">I am over here</div>
    </div>
  </div>

  <div id="bug5022" style="overflow:hidden; height:0; width:0;">
    This is a zero height/width div and overflow hidden
  </div>

  <div style="overflow:hidden; height:0; width:0;">
    <div id="overflowHiddenWithFixedPositionChild">
      This is a zero height/width div and overflow hidden
      <div id="fixedPositionChild" style="position:fixed"></div>
    </div>
  </div>

  <div style="position:relative;
            width:300px;
            height:300px;
            background-image:url(testdata/kitten1.jpg);
            background-position:center;">
    <a id="bug5109" href="kitten2.jpg" style="display:block;
           position:relative;
           width:100px;
           height:100px;
           left:-60px;
           top:-66px;
           background-image:url(testdata/kitten2.jpg);
           background-position:center;"></a>
  </div>

  <div id="negativePositionWithPositivePositionChildren" style="position:absolute;left:-10px;top:-10px">
    <div style="position:absolute;left:100px;top:100px">
      positivePositionChildInNegativePositionParent
    </div>
  </div>
  <div id='html5hidden' hidden>This is not visible</div>

  <div style="display: contents; overflow-y: auto">
    <input id="displayContentsInput" />
  </div>

  <table>
    <tr id="visible-row">
      <td>a</td>
    </tr>
    <tr id="collapsed-row" style="visibility:collapse">
      <td>b</td>
    </tr>
    <tr id="post-collapsed-row">
      <td>c</td>
    </tr>
  </table>

  <details>
    <summary id="summary">Some Summary</summary>
    <div id="non-summary">
      <p>More text</p>
    </div>
  </details>

  <div id='contentVisibility' style='content-visibility: hidden'>
    A
    <div id='b'>B</div>
  </div>

  <div id='nestedTextNode' style='width: 0px; overflow: visible'>
    <div style="display: none;">text</div>
  </div>

</body>

</html>
